#!/usr/bin/env python
"""Puttable HTTP Server.

This module builds on SimpleHTTPServer implementing PUT and POST
to put files. Note this is really dangerous!! Just for test.

Port can be specified as the first (and only) argument.
"""
__version__ = "0.1"
__all__ = ["SimpleHTTPRequestHandler"]
import os
import sys
import BaseHTTPServer
import SimpleHTTPServer

class PuttableHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):

    server_version = "PuttableHTTP/" + __version__
    def do_PUT(self):
        """Serve a PUT request."""
        if self.headers.getheader('expect') == '100-continue':
            self.send_response(100, 'continue')
            self.wfile.flush()
        self.do_POST()

    def do_POST(self):
        """Serve a POST request."""
        self._writeOut(os.path.join(os.getcwd(), self.path[1:]), self.rfile)
        self.send_header("Content-Length", "0")
        self.end_headers()
        self.wfile.flush()

    def _copyCont(self, src, dest, length):
        buflen = 10000
        while length > 0:
            b = src.read(min(buflen, length))
            dest.write(b)
            length = length - len(b)

    def _writeOut(self, path, f):
        if path.find('/../') >= 0:
            self.send_response(403, "forbidden")
            return
        length = self.headers.getheader('content-length')
        if not length:
            self.send_response(411, "length required")
            return;
        try:
            existFlag = os.path.exists(path)
            dest = file(path, 'w')
            self._copyCont(f, dest, int(length))
            dest.close()
            if existFlag:
                self.send_response(204, "post succeeded, modified")
                return
            else:
                self.send_response(201, "post succeeded")
                return
        except IOError, msg:
            self.send_response(401, "faield to writefile," + msg)
            return

def test(HandlerClass = PuttableHTTPRequestHandler,
         ServerClass = BaseHTTPServer.HTTPServer):
    print HandlerClass.protocol_version
#    BaseHTTPServer.test(HandlerClass, ServerClass, protocol="HTTP/1.1")
    BaseHTTPServer.test(HandlerClass, ServerClass)

if __name__ == '__main__':
    test()
